package icu.d4peng.cloud.common.log.context;

import com.alibaba.ttl.TransmittableThreadLocal;
import icu.d4peng.cloud.common.log.bean.LogBean;
import icu.d4peng.cloud.common.log.generator.spanid.DefaultSpanIdGenerator;
import icu.d4peng.cloud.common.log.generator.spanid.SpanIdGenerator;
import icu.d4peng.cloud.common.log.generator.traceid.DefaultTraceIdGenerator;
import icu.d4peng.cloud.common.log.generator.traceid.TraceIdGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author d4peng
 * @version 1.0.0
 * @date 2021-12-27 14:09
 * @description LogContext:日志上下文记录
 */
public class LogContext {
    private static final Logger LOGGER = LoggerFactory.getLogger(LogContext.class);
    /**
     * TraceId上下文
     */
    private static final ThreadLocal<String> TRACE_ID_TL = new TransmittableThreadLocal<String>();
    /**
     * 当前ip上下文
     */
    private static final ThreadLocal<String> CURRENT_IP_TL = new TransmittableThreadLocal<String>();
    /**
     * 上游APP上下文
     */
    private static final ThreadLocal<String> PRE_APP_TL = new TransmittableThreadLocal<String>();
    /**
     * 上游主机上下文
     */
    private static final ThreadLocal<String> PRE_HOST_TL = new TransmittableThreadLocal<String>();
    /**
     * 上游IP上下文
     */
    private static final ThreadLocal<String> PRE_IP_TL = new TransmittableThreadLocal<String>();
    /**
     * 扩展信息上下文
     */
    private static final ThreadLocal<String> EXT_DATA_TL = new TransmittableThreadLocal<String>();
    /**
     * 是否开启了MDC
     */
    private static boolean enableMDC = false;
    /**
     * MDC默认样式
     */
    private static String MDCPattern = "<traceId:$traceId><spanId:$spanId><currentIp:$currentIp><preApp:$preApp><preHost:$preHost><preIp:$preIp>";
    /**
     * traceId生成器
     */
    private static TraceIdGenerator traceIdGenerator = new DefaultTraceIdGenerator();
    /**
     * spanId生成器
     */
    private static SpanIdGenerator spanIdGenerator = new DefaultSpanIdGenerator();

    public static String getTraceId() {
        return TRACE_ID_TL.get();
    }

    public static void setTraceId(String traceId) {
        TRACE_ID_TL.set(traceId);
    }

    public static void clearTraceId() {
        TRACE_ID_TL.remove();
    }

    public static String getSpanId() {
        return spanIdGenerator.getSpanId();
    }

    public static void setSpanId(String spanId) {
        spanIdGenerator.setSpanId(spanId);
    }

    public static void clearSpanId() {
        spanIdGenerator.remove();
    }

    public static String getCurrentIp() {
        return CURRENT_IP_TL.get();
    }

    public static void setCurrentIp(String currentIp) {
        CURRENT_IP_TL.set(currentIp);
    }

    public static void clearCurrentIp() {
        CURRENT_IP_TL.remove();
    }

    public static String getPreApp() {
        return PRE_APP_TL.get();
    }

    public static void setPreApp(String preApp) {
        PRE_APP_TL.set(preApp);
    }

    public static void clearPreApp() {
        PRE_APP_TL.remove();
    }

    public static String getPreHost() {
        return PRE_HOST_TL.get();
    }

    public static void setPreHost(String preHost) {
        PRE_HOST_TL.set(preHost);
    }

    public static void clearPreHost() {
        PRE_HOST_TL.remove();
    }

    public static String getPreIp() {
        return PRE_IP_TL.get();
    }

    public static void setPreIp(String preIp) {
        PRE_IP_TL.set(preIp);
    }

    public static void clearPreIp() {
        PRE_IP_TL.remove();
    }

    public static String getExtData() {
        return EXT_DATA_TL.get();
    }

    public static void setExtData(String extData) {
        EXT_DATA_TL.set(extData);
    }

    public static void clearExtData() {
        EXT_DATA_TL.remove();
    }

    public static boolean isEnableMDC() {
        return enableMDC;
    }

    public static void setEnableMDC(boolean enableMDC) {
        LogContext.enableMDC = enableMDC;
    }

    public static String getMDCPattern() {
        return MDCPattern;
    }

    public static void setMDCPattern(String MDCPattern) {
        LogContext.MDCPattern = MDCPattern;
    }

    public static TraceIdGenerator getTraceIdGenerator() {
        return traceIdGenerator;
    }

    public static void setTraceIdGenerator(TraceIdGenerator traceIdGenerator) {
        LogContext.traceIdGenerator = traceIdGenerator;
    }

    public static SpanIdGenerator getSpanIdGenerator() {
        return spanIdGenerator;
    }

    public static void setSpanIdGenerator(SpanIdGenerator spanIdGenerator) {
        LogContext.spanIdGenerator = spanIdGenerator;
    }

    /**
     * 利用MDCPattern生成日志信息
     *
     * @param logBean 日志信息
     * @return 日志信息
     */
    public static String generateMDCLabel(LogBean logBean) {
        return LogContext.MDCPattern
                .replace("$traceId", logBean.getTraceId())
                .replace("$spanId", logBean.getSpanId())
                .replace("$currentIp", logBean.getCurrentIp())
                .replace("$preApp", logBean.getPreApp())
                .replace("$preHost", logBean.getPreHost())
                .replace("$preIp", logBean.getPreIp());
    }
}
